package ivan.bookKeeper;

import java.sql.Date;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.concurrent.ExecutionException;

import so.book.AddBook;
import so.book.DeleteBook;
import so.book.ReturnAllBooks;
import so.book.ReturnBooks;
import so.bookFromLibrary.AddBookFromLibrary;
import so.library.ReturnAllLibraries;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import domain.Book;
import domain.BookFromLibrary;
import domain.Library;

public class ListBookActivity extends ListActivity implements OnClickListener,
		OnLongClickListener {
	private static final String TAG = ListBookActivity.class.getSimpleName();
	private TextView addButton_textView;
	private static ArrayList<Book> booksList;
	private LayoutInflater inflaterBook;
	private View dialogView;
	private BookHolder bookHolder;
	private Book book;
	private BookAdapter bookAdapter;
	private ArrayAdapter<Library> libraryAdapter;
	private Library selectedLibrary;
	private BookFromLibrary bookFromLibrary;
	private static int positionOnExit = 0; // determines the position in the
											// list of books on restart of this
											// activity

	// ///// on create list activity stuff
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.list_all_books);
		getAllBooks(this);
		bookAdapter = new BookAdapter(this);
		setListAdapter(bookAdapter);

		inflaterBook = LayoutInflater.from(this);

		addButton_textView = (TextView) findViewById(R.id.addBook_textView);
		getLibraries();
		addButton_textView.setOnClickListener(this);
		addButton_textView.setOnLongClickListener(this);
		registerForContextMenu(this.getListView());
	}

	@Override
	protected void onRestart() {
		super.onRestart();
		// // sets the list to the last viewed book
		getAllBooks(this);
		bookAdapter.notifyDataSetChanged();
		setSelection(positionOnExit);
		Log.d(TAG, "Activity RESTARTED!!!");
	}

	// ///// on textView button click (add new book) - opens the dialogue
	@Override
	public void onClick(View v) {
		dialogView = inflaterBook.inflate(R.layout.alert_dialog_enter_book,
				null);
		AlertDialog.Builder builder = new Builder(ListBookActivity.this);
		bookHolder = new BookHolder();

		bookHolder.libraryList_spinner = (Spinner) dialogView
				.findViewById(R.id.spinnerLibraries);
		bookHolder.libraryList_spinner.setAdapter(libraryAdapter);
		Log.d(TAG, "Library Adapter set for spinner inside dialogue");
		bookHolder.libraryList_spinner
				.setOnItemSelectedListener(onLibrarySelected);

		builder.setView(dialogView)
				.setIcon(android.R.drawable.ic_input_add)
				.setTitle(getString(R.string.book_add_text) + ":")
				.setPositiveButton(R.string.book_add_text,
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								bookHolder.bookName_editText = (EditText) dialogView
										.findViewById(R.id.bookName);
								bookHolder.bookAuthor_editText = (EditText) dialogView
										.findViewById(R.id.bookAuthor);

								book = new Book();
								String bookName = bookHolder.bookName_editText
										.getText().toString();
								String bookAuthor = bookHolder.bookAuthor_editText
										.getText().toString();
								if (!(bookName.equals(""))
										&& (!(bookAuthor.equals("")))) {
									book.setBookName(bookName);
									book.setBookAuthor(bookAuthor);
									new AddBook(ListBookActivity.this)
											.execute(book);

									// gets the book's id!!
									AsyncTask<Object, Object, Object> returnBook = new ReturnBooks(
											ListBookActivity.this)
											.execute(book);
									Cursor cursor = null;

									try {
										cursor = (Cursor) returnBook.get();
										cursor.moveToNext();
										// sets the book's id!
										book.setBookID(cursor.getInt(cursor
												.getColumnIndexOrThrow("bookID")));
										// sets the current date
										Date date = new Date(Calendar
												.getInstance().getTime()
												.getTime());
										// creates a bookFromLibrary object
										bookFromLibrary = new BookFromLibrary(
												book.getBookID(),
												selectedLibrary.getLibraryID(),
												date.getTime());
										// calls SO for inserting in db
										new AddBookFromLibrary(
												ListBookActivity.this)
												.execute(bookFromLibrary);
										// log it!
										Log.d(TAG,
												"INSERTED BOOK FROM LIBRARY IN DB:"
														+ bookFromLibrary
																.toString());

									} catch (InterruptedException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									} catch (ExecutionException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									}

									showLongToast(book.toString()
											+ " "
											+ getString(R.string.toastMessage_success_add));
									booksList.add(book);
									bookAdapter.notifyDataSetChanged();
									setSelection(booksList.indexOf(book));
								} else {
									showLongToast(getString(R.string.toastMessage_error_noInput));
								}

							}
						})
				.setNegativeButton(R.string.txt_cancel,
						new DialogInterface.OnClickListener() {

							@Override
							public void onClick(DialogInterface dialog,
									int which) {
								dialog.cancel();
								Log.d(TAG,
										"User canceled the entering of the new book");
							}
						});
		builder.create();
		builder.show();
	}

	private static class BookHolder {
		EditText bookName_editText;
		EditText bookAuthor_editText;
		Spinner libraryList_spinner;
	}

	// // helper function for getting ALL the libraries from db!
	private void getLibraries() {
		libraryAdapter = new ArrayAdapter<Library>(ListBookActivity.this,
				R.layout.library_row, R.id.libraryName);

		Library library = new Library();
		AsyncTask<Object, Object, Object> returnAllLibraries = new ReturnAllLibraries(
				ListBookActivity.this).execute(library);

		Cursor cursor = null;
		try {
			cursor = (Cursor) returnAllLibraries.get();
			if (cursor == null)
				showLongToast(getString(R.string.toastMessage_error_noLibrariesInDB));
			else {
				while (cursor.moveToNext()) {
					library = new Library(cursor.getInt(0), cursor.getInt(1),
							cursor.getInt(2), cursor.getString(3),
							cursor.getString(4), cursor.getString(5),
							cursor.getString(6));
					libraryAdapter.add(library);
					Log.d(TAG, "new library: " + library.toString());
				}
				Log.d(TAG,
						"Finished fetching libraries: adapter completed with data");
			}

		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// //// on item selected listener for libraries inside spinner (in dialog)
	// !!
	OnItemSelectedListener onLibrarySelected = new OnItemSelectedListener() {
		@Override
		public void onItemSelected(AdapterView<?> arg0, View arg1,
				int position, long arg3) {
			selectedLibrary = libraryAdapter.getItem(position);
			Log.d(TAG, "Library selected: " + selectedLibrary.toString());
		}

		@Override
		public void onNothingSelected(AdapterView<?> arg0) {
		}
	};

	// ///// on text view button long click - starts the AddBook Activity
	@Override
	public boolean onLongClick(View v) {
		Intent intent = new Intent(ListBookActivity.this, AddBookActivity.class);
		startActivity(intent);

		return false;
	}

	// // get all books & populate the array
	private void getAllBooks(Context context) {
		booksList = new ArrayList<Book>();
		Book book = new Book();
		AsyncTask<Object, Object, Object> getAllBooksTask = new ReturnAllBooks(
				this).execute(book);
		try {
			Cursor cursor = (Cursor) getAllBooksTask.get();
			while (cursor.moveToNext()) {
				int bookID = cursor.getInt(cursor
						.getColumnIndexOrThrow("bookID"));
				String bookName = cursor.getString(cursor
						.getColumnIndexOrThrow("bookName"));
				String bookAuthor = cursor.getString(cursor
						.getColumnIndexOrThrow("bookAuthor"));
				int bookYear = cursor.getInt(cursor
						.getColumnIndexOrThrow("bookYear"));
				String bookPublisher = cursor.getString(cursor
						.getColumnIndexOrThrow("bookPublisher"));
				String bookLanguage = cursor.getString(cursor
						.getColumnIndexOrThrow("bookLanguage"));
				String bookISBN = cursor.getString(cursor
						.getColumnIndexOrThrow("bookISBN"));

				book = new Book(bookYear, bookName, bookAuthor, bookPublisher,
						bookLanguage, bookISBN);
				book.setBookID(bookID);
				booksList.add(book);
				Log.d(TAG, book.getBookID() + " " + book.toString());

			}

		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// ////////// private class adapter
	private static class BookAdapter extends BaseAdapter {
		private LayoutInflater inflater;
		private Context context;

		public BookAdapter(Context context) {
			inflater = LayoutInflater.from(context);
			this.context = context;
		}

		@Override
		public int getCount() {
			return booksList.size();
		}

		@Override
		public Object getItem(int position) {
			return booksList.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			final ViewHolder holder;

			if (convertView == null) {
				convertView = inflater.inflate(R.layout.book_row, null);

				holder = new ViewHolder();

				holder.bookName_textView = (TextView) convertView
						.findViewById(R.id.bookName);
				holder.bookAuthor_textView = (TextView) convertView
						.findViewById(R.id.bookAuthor);
				// very important!!
				convertView.setTag(holder);
			} else {
				// get from tag
				holder = (ViewHolder) convertView.getTag();
			}

			holder.bookName_textView.setText(booksList.get(position)
					.getBookName());
			holder.bookAuthor_textView.setText(booksList.get(position)
					.getBookAuthor());
			holder.pos = position;

			// ///////// sets click listener for opening the edit book
			// activity!!
			convertView.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					Book selectedBook = booksList.get(holder.pos);
					Intent intent = new Intent(context, AddBookActivity.class);
					Bundle bundle = new Bundle();
					bundle.putInt("bookID", selectedBook.getBookID());
					bundle.putString("bookName", selectedBook.getBookName());
					bundle.putString("bookAuthor", selectedBook.getBookAuthor());
					bundle.putString("bookISBN", selectedBook.getBookISBN());
					bundle.putString("bookPublisher",
							selectedBook.getBookPublisher());
					bundle.putString("bookLanguage",
							selectedBook.getBookLanguage());
					bundle.putInt("bookYear", selectedBook.getBookYear());
					intent.putExtras(bundle);
					positionOnExit = holder.pos;
					context.startActivity(intent);
				}
			});

			// ///////// end click listener
			convertView.setOnLongClickListener(new OnLongClickListener() {
				@Override
				public boolean onLongClick(View v) {
					Log.d(TAG, "LONG CLICK IN CONVERT VIEW!!");
					return false;
				}
			});
			return convertView;
		}

		static class ViewHolder {
			TextView bookName_textView;
			TextView bookAuthor_textView;
			int pos;
		}
	}

	// ///---- context menu stuff
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		if (v.getId() == this.getListView().getId()) {
			super.onCreateContextMenu(menu, v, menuInfo);
			menu.setHeaderTitle(getString(R.string.contextMenu_title));
			menu.add(0, 1, 0, "Opcija 1")
					.setTitle(R.string.contextMenu_editOption)
					.setIcon(android.R.drawable.ic_menu_edit);
			menu.add(0, 2, 0, "Opcija 2")
					.setTitle(R.string.contextMenu_deleteOption)
					.setIcon(android.R.drawable.ic_delete);
		}
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		final AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) item
				.getMenuInfo();

		Book selectedBook = (Book) ListBookActivity.this.getListAdapter()
				.getItem(menuInfo.position);

		switch (item.getItemId()) {
		case 1:

			Intent intent = new Intent(ListBookActivity.this,
					AddBookActivity.class);
			Bundle bundle = new Bundle();
			bundle.putInt("bookID", selectedBook.getBookID());
			bundle.putString("bookName", selectedBook.getBookName());
			bundle.putString("bookAuthor", selectedBook.getBookAuthor());
			bundle.putString("bookISBN", selectedBook.getBookISBN());
			bundle.putString("bookPublisher", selectedBook.getBookPublisher());
			bundle.putString("bookLanguage", selectedBook.getBookLanguage());
			bundle.putInt("bookYear", selectedBook.getBookYear());
			intent.putExtras(bundle);
			positionOnExit = menuInfo.position;
			ListBookActivity.this.startActivity(intent);
			break;
		case 2:
			AlertDialog.Builder builder = new Builder(ListBookActivity.this);
			builder.setIcon(android.R.drawable.ic_menu_delete);
			builder.setTitle(getString(R.string.dialogTitle_delete));
			builder.setMessage(getString(R.string.dialogMessage_confirm_delete))
					.setPositiveButton(
							getString(R.string.dialogMessage_confirm),
							new DialogInterface.OnClickListener() {

								@Override
								public void onClick(DialogInterface dialog,
										int which) {
									new DeleteBook(ListBookActivity.this)
											.execute(booksList
													.get(menuInfo.position));
									Log.d(TAG, "BOOK Position DELETED: "
											+ menuInfo.position);
									booksList.remove(menuInfo.position);
									bookAdapter.notifyDataSetChanged();
								}
							})
					.setNegativeButton(getString(R.string.txt_cancel),
							new DialogInterface.OnClickListener() {

								@Override
								public void onClick(DialogInterface dialog,
										int which) {
									dialog.dismiss();
								}
							}).show();
			break;
		}
		return false;
	}

	// ///------- context menu stuff end

	private void showLongToast(String text) {
		Toast.makeText(ListBookActivity.this, text, Toast.LENGTH_LONG).show();
	}
}
